% vim: ts=8 sts=8 sw=4 et tw=75
\chapter{前言}
\label{chap:preface}

\marginpar{iii}
计算机用户经常把大量的时间花费在简单, 机械化的数据处理工作中 --- 改变
数据格式, 验证数据的有效性, 搜索特定的数据项, 求和, 打印报表等. 这些
工作完全可以自动化地完成, 但是如果每碰到一个这样的任务, 就用一门标准
的编程语言 (比如 C 或 Pascal) 写一个专用的程序来解决它, 未免也太麻烦了.

Awk 是一门特殊的编程语言, 它非常适合处理上面提到的任务, 经常只需要
一两行便可搞定. 一个 awk 程序由一系列的模式和动作组成, 这些模式与动作
说明了在输入中搜索哪些数据, 以及当符合条件的数据被找到时, 应该执行什么
操作. Awk 在输入文件集合中 搜索与模式相匹配的输入行, 当找到一个匹配行时, 
便会执行对应的动作. 通过字符串, 数值, 字段, 变量和数组元素的比较操作,
再加上正则表达式, 利用这些组合, 一个模式可以用来选择输入行, 而动作可以
对选中的行作任意的处理. 描述动作的语言看起来和 C 非常像, 但是它不需要
声明, 并且字符串和数值都是内建的数据类型.

Awk 自动地扫描输入文件, 并把每一个输入行切分成字段. 因为许多工作都是
自动完成的 --- 包括输入, 字段分割, 存储管理, 初始化 --- 所以和传统语言
编写的程序相比, awk 程序简短得多. Awk 最常用的用途就是前面提到的
那些工作. 因为 awk 程序一般都很短, 所以人们经常这样使用它: 通过键盘在
命令行中输入程序代码 (只有一两行), 执行, 然后把代码丢弃. 实际上, awk 是
一个通用编程工具, 许多专用工具都可以用它来替代.

由于表达式和操作非常简便, 所以用 awk 构造大型程序的原型就显得非常方便:
先从简单的几行开始, 慢慢加以扩充, 测试不同的设计方案, 直到完成预期的目标.
因为程序比较简短, 所以很容易上手, 如果在开发的过程中想到了一个更好的方案,
修改起来 (甚至从头开始) 也没那么麻烦. 只要设计是正确的, 那么把 awk 程序
翻译成其他语言也很方便.
\marginpar{iv}

\section*{本书组织}
本书的第一目标是告诉读者 awk 是什么, 以及如何高效地使用它. 第 
\ref{chap:an_awk_tutorial} 章是一个快速入门教程, 读过几页之后, 读者应该就
有了足够的知识开始写一些有用的 awk 程序. 这一章的例子非常简短, 它
们都是 awk 的典型应用.

第 \ref{chap:the_awk_language} 章对整个 awk 语言进行描述. 虽然这一章
也包含了许多例子, 但是读起来就像手册一样枯燥, 所以在第一次阅读本章
时, 快速浏览即可.

本书的剩下几章包含了相当丰富的例子, 这些例子主要用来展示 awk 的应用范围
如何广泛, 以及如何高效地使用它. 其中一些示例比较常规, 另外一些虽然展示
了某些编程思想, 但并没有非常实际的用途, 还有一小部分例子仅仅是因为
它们比较有趣.

第 \ref{chap:data_processing} 章的重点是检索, 转换, 归约和数据验证  ---
这些任务本来就是当初开发 awk 的目标. 这一章还讨论了如何处理多行记录, 比如
地址薄.

Awk 是管理小型个人数据库的优秀工具. 第 \ref{chap:reports_and_databases}
章讨论如何从数据库中生成报表, 以及如何为存储在多个文件中的数据
构造一个简单的关系数据库系统和对应的查询语言.

Awk 处理文本就像其他语言处理数值一样方便, 所以它经常被应用在文本
处理领域. 第 \ref{chap:processing_words} 章讨论如何使用 awk 生成文本,
以及协助文档的准备工作. 这一章包含了一个索引生成程序, 本书的索引就是用它
的增强版生成的.

第 \ref{chap:little_languages} 章关于 ``小语言'', 小语言指的是特定
于某个领域的定制化语言. 使用 awk 编写翻译器非常方便, 因为它的基本操作
支持大部分的词汇和表格管理工作. 这一章包含汇编程序, 绘图程序和
几个计算器程序.

Awk 还可以用来演示算法. 因为用 awk 写程序不需要声明, 也不用担心内存管理,
所以它不仅具有伪代码的许多优点, 而且是可运行的. 第
\ref{chap:experiments_with_algorithms} 讨论算法实验, 包括测试与性能
评价. 算法包括几种排序算法, 最后以 Unix 程序 \texttt{make} 作为结束.

第 \ref{chap:epilog} 章介绍 awk 的历史. 除此之外, 如果程序比较慢, 或者条
件比较苛刻, 这一章还提出了几点优化建议.

附录 \ref{chap:awk_summary} 总结了 awk 语言, 附录
\ref{chap:answers_to_selected_exercises} 是部分习题的参考答案.

读者应该从第 \ref{chap:an_awk_tutorial} 章开始阅读, 并尝试自己动手写
程序. 快速浏览第 \ref{chap:the_awk_language} 章, 重点关注汇总和表格,
不要陷入到细节当中. 然后根据自己的兴趣, 阅读后面的章节, 这些章节之间
都是互相独立的, 所以不用在意阅读顺序.
\marginpar{v}
\section*{示例}
示例覆盖了多个主题, 但其中最重要的是向读者展示如何高效地使用 awk. 我们
已经努力让书中的例子覆盖尽可能多的程序结构, 对关联数组和正则表达式有所侧重,
因为它们是 awk 编程的主要特点.

第 2 个主题是展示 awk 丰富的功能. 从数据库到芯片设计, 从数值分析到图形
图像, 从编译器到系统管理, 从非编程人员的第一门语言到软件工程课的实现
语言 --- 都可以见到 awk 的身影. 我们希望书中的例子也能够让读者有所启发.

第 3 个主题展示的是如何完成一些常见的计算操作. 相关的例子包括关系型数据
库, 玩具计算机的汇编程序和解释程序, 绘图语言, awk 子集的递归下降语法
分析器, 基于 \texttt{make} 的文件更新程序等. 在每个案例中, 都会有一
个简短的程序, 向读者展示操作过程中最核心的部分, 以便快速理解和动手
实践.

另外, 我们还会向读者说明解决编程问题的一系列方法. Awk 对快速原型开发
方法支持得很好, 另外一种不太明显的策略是分而治之 --- 把一件大任务分成
几个小任务, 每一个小任务集中解决问题的某一方面. 最后一种方法是开发一个
用来生成其他程序的程序. 通过开发小语言, 我们可以更加容易地定义出良好
的用户接口, 以及更合理的实现方案. 虽然前面提到的方法是在 awk 的环境
中提出, 但实际上, 它们都是非常通用的编程方法, 每一位程序员都应该掌握.

书中所有的例子都是直接从文本中加以测试, 这些文本都是以机器可读的形式
呈现. 我们已经尽力让这些示例程序不含有错误, 但是我们既没有为它们添加
特性, 也没有用所有可能的无效数据对它们进行测试: 这些程序的目标主要是用
来说明问题.

\section*{AWK 的演变}

Awk 最早由本书作者在 1977 年设计并实现, 当时是作为实验的一部分, 而这个实
验是为了检查 Unix 工具 \texttt{grep} 和 \texttt{sed} 是否可以像处理文本
那样处理数值. Awk 的开发基于我们对正则表达式和可编程编辑器的兴趣. 虽然 
开发 awk 是为了写出非常简短的程序, 但是它丰富的功能马上吸引了众多用户,
而这些用户经常开发大型程序, 这些大型程序需要 awk 提供更多的功能, 因此在
1985 年, awk 推出了一个增强版.

增强版增加的一个主要特性是允许用户定义自己的函数.
\marginpar{vi}
其他的增强功能包括动态正则表达式 --- 带有文本替换和模式匹配功能; 更丰富
的内建函数与变量; 新增的运算符和语句; 从多个文件中读取输入数据; 命令行 
参数的支持. 出错时的消息提示也得到了加强. 第 \ref{chap:an_awk_tutorial}
章的例子只使用了原版 awk 的功能, 而后面的例子则用到了许多新增的特性.

本书的 awk 版本是 Unix System V Release 3.1 的一部分, 其源代码可以
通过 AT\&T 的 Unix System Toolchest 软件发行系统得到, 具体方式是拨打
1-201-522-6900, 并以访客身份登录; 如果是欧洲地区, 请联系位于伦敦的 AT\&T
Unix Europe (44-1-567-7711); 如果是远东地区, 请联系位于东京的
AT\&T Unix Pacific (81-3-431-3670).

因为 awk 在 Unix 系统中开发而成, 所以它的某些功能只能在 Unix 系统使用,
有几个例子使用了这些和操作系统相关的功能.
另外, 我们还假设系统中提供了某些 Unix 实用工具, 尤其是  \texttt{sort}.
除了这些限制条件, awk 应该能在多种平台中使用, 尤其是它也能在 MS-DOS 中
运行, 更多的信息请咨询 Addison-Wesley.

Awk 并不完美, 它也有一些例外, 遗漏, 或者仅仅是一些不好的设计导致的, 有时
候它还会很慢. 但它同时也是一门功能丰富的语言, 可以解决许多编程问题,
希望读者能像我们一样, 从 awk 中得到巨大的帮助.

\section*{致谢}
本书的写作过程得到了许多人的帮助, 我们由衷地感谢他们, 尤其是 Jon Bentley,
他的热情始终鼓舞着我们. Jon 为本书的创作提供了许多想法和程序, 这些都来源
于他长期使用和教授 awk 积累下来的经验, 他还认真地阅读了本书的部分草稿.
另外, 我们还要感谢 Doug McIlroy, 作为一名出色的读者, 他帮助我们改善了
整本书的结构和内容. 其他人还包括 Susan Aho, Jaap Akkerhuis, Lorinda
Cherry, Chris Fraser, Eric Grosse, Riccardo Gusella, Bob Herbst, Mark
Kernighan, John Linderman, Bob Martin, Howard Moscovitz, Gerard Schmitt,
Don Swartwout, Howard Trickey, Peter van Eijk, Chris Van Wyk, 和 Mihalis
Yannakakis, 谢谢他们的帮助.

\begin{flushright}
Alfred V. Aho\par
Brian W. Kernighan \par
Peter J. Weinberger
\end{flushright}
